home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
011
/
scrnsav2.arc
/
SCRNSAV2.ASM
next >
Wrap
Assembly Source File
|
1985-04-06
|
6KB
|
204 lines
; ---------------------------------------------------------------
; Program SCRNSAVE.COM to blank the screen after two minutes of
; inactivity. This program is based on the program BLANK.COM
; submitted by Christopher Wiley in PC World Volume 2 Number 4
; and later modified by Steve Cook and printed in PC World Volume
; 2 Number 11. Subsequent modifications include the addition of
; a message to the user and use of INT 21H function 31H instead
; of INT 27H.
;
; This utility works well with both the IBM Color and Monochrome
; Displays -- even after issuing a MODE command to change
; displays after this program has run!
; ---------------------------------------------------------------
;
; Define the code segment, and set things up for a .COM program
;
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CSEG,DS:CSEG
;
; Programs which are to be put through EXE2BIN must start at address
; 100H so...
;
ORG 100H
;
START: JMP GO ; jump around the data area
;
SWFLAG DB 0 ; video not switched off (1 if we did)
KEYFLAG DB 0 ; no key input nor display since video off
COUNT DW 0 ; timer count
;
ADDR_6845 EQU 63H ; CRT control port base address
CRT_MODE_SET EQU 65H ; current state of CRT mode register
;
;
; timer tick interrupt with occurs 18.2 times per second
;
TICKER:
STI ; restore interrupts
PUSH AX ; save registers
PUSH DS
PUSH CS ; set DS to code segment
POP DS
CMP SWFLAG,0 ; is the video already off ?
JNE T01 ; yes, jump to T01
INC COUNT ; no, keep counting clock pulses
CMP COUNT,0888H ; until we get to 2 minutes
JNAE T02 ; if we hit limit, jump to T02
MOV COUNT,0 ; yes, reset counter to zero
PUSH DX ; save these registers too
PUSH ES ; Now to switch the video off
MOV AX,0040H ; (base address of ROM data area)
MOV ES,AX
MOV DX,ES:ADDR_6845 ; Get base address of video controller
ADD DX,4 ; point to controller's mode register
MOV AL,ES:CRT_MODE_SET ;Get current mode settings
AND AL,11110111B ; Clear the video enable bit to
OUT DX,AL ; turn off the video.
POP ES
POP DX
MOV SWFLAG,1 ; flag video as switched off
JMP SHORT T02 ; standard exit
T01:
CMP KEYFLAG,0 ; We have switched off. Has a key been
; pressed or attempt been made to DS
JE T02 ; display a character since then? No.
PUSH DX ; Yes. Restore video signal
PUSH ES
MOV AX,0040H ; First, point to the ROM data area
MOV ES,AX
MOV DX,ES:ADDR_6845 ; Get base address of video controller
ADD DX,4 ; and point to controller mode register
MOV AL,ES:CRT_MODE_SET ; Get the old mode settings and
OUT DX,AL ; restore them
POP ES
POP DX
MOV KEYFLAG,0 ; Reset the flags as: No key in/video
MOV SWFLAG,0 ; not switched
MOV COUNT,0 ; reset (again) count to 0
T02:
POP DS ; standard exit. Restore Used Registers
POP AX ; and process whatever was at INT 1CH
INT 60H ; before this program was invoked
IRET
;
; The user has pressed a key on the keyboard
;
KEY_IN:
STI ; restore interrupts
PUSH AX ; save registers
PUSH DS
PUSH CS ; set DS to code segment
POP DS
CMP SWFLAG,0 ; is the video already off ?
JE K01 ; no
MOV KEYFLAG,1 ; Yes, set theflag that we got a key
INT 1CH
K01:
MOV COUNT,0 ; yes, reset counter to zero
POP DS ; restore the saved register and inform
POP AX ; the system by causing the equivalent
INT 61H ; of an INT 09H in this program
IRET
;
; The system wants to write something to the screen
;
VIDEO_OUT:
STI ; restore interrupts
PUSH AX ; save registers
PUSH DS
PUSH CS ; set DS to code segment
POP DS
CMP SWFLAG,0 ; is the video already off ?
JE V01 ; no
MOV KEYFLAG,1 ; Yes, set the flag that we want it on
INT 1CH
V01:
MOV COUNT,0 ; yes, reset counter to zero
POP DS ; restore the saved register and inform
POP AX ; the system by causing the equivalent
INT 62H ; of an INT 10H in this program
IRET
;
END_PR: ; used to determine length of program
;
GO:
MOV AH,35H ; get address of 1C vector (timer 18.2
MOV AL,1CH ; timer per second frequency)
INT 21H
PUSH ES ; move ES:BX to DS:DX
PUSH BX
POP DX
POP DS
MOV AH,25H ; set into interrupt 60H as replacement
MOV AL,60H
INT 21H
;
MOV AH,35H ; Do same for keyboard interrupt
MOV AL,09H
INT 21H
PUSH ES
PUSH BX
POP DX
POP DS
MOV AH,25H ; set into interrupt 61H as replacement
MOV AL,61H
INT 21H
;
MOV AH,35H ; Do same for video interrupt
MOV AL,10H
INT 21H
PUSH ES
PUSH BX
POP DX
POP DS
MOV AH,25H ; set into interrupt 62H as replacement
MOV AL,62H
INT 21H
;
PUSH CS ; now set new values in the vector 1CH
POP DS
MOV DX,OFFSET TICKER
MOV AH,25H
MOV AL,1CH
INT 21H ; as timer tick interrupt
;
PUSH CS ; now set new values in the vector 09H
POP DS
MOV DX,OFFSET KEY_IN
MOV AH,25H
MOV AL,09H
INT 21H ; as keyboard interrupt
;
PUSH CS ; now set new values in the vector 10H
POP DS
MOV DX,OFFSET VIDEO_OUT
MOV AH,25H
MOV AL,10H
INT 21H ; as video interrupt
;
PUSH CS ; now send message to screen
POP DS
MOV DX,OFFSET MESSAGE
MOV AH,09H
INT 21H
;
PUSH CS ; set DS to CS
POP DS
MOV DX,OFFSET END_PR ; Set DX to length of modules
SHR DX,1 ; to remain resident and divide
SHR DX,1 ; by 16 to get the length in
SHR DX,1 ; paragraphs
SHR DX,1
INC DX
MOV AH,31H ; invoke DOS function to leave
MOV AL,00 ; terminate and leave these
INT 21H ; modules resident
;
MESSAGE DB 'Screen saver in effect with a two-minute timeout'
CRLF DB 0DH,0AH
DB '$'
;
CSEG ENDS
END START